package com.example.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.example.article.mapper.ArticleMapper;
import com.example.article.service.HotArticleService;
import com.example.common.constants.ArticleConstants;
import com.example.common.redis.CacheService;
import com.example.common.util.R;
import com.example.feignapi.wemedia.WemediaClient;
import com.example.model.article.pojo.Article;
import com.example.model.article.vo.HotArticleVo;
import com.example.model.wemedia.pojo.Channel;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class HotArticleServiceImpl implements HotArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private WemediaClient wemediaClient;
    @Autowired
    private CacheService cacheService;

    /**
     * 计算热点文章
     * @return
     */
    @Override
    public boolean computeHotArticle() {
        // 1、查询前5天的文章数据
        Date date = DateTime.now().minusDays(200).toDate();
        List< Article > articleList = articleMapper.getArticleListByLast5days(date);

        // 2、计算文章分值
        List< HotArticleVo > hotArticleVoList = computeHotArticle(articleList);

        // 3、为每个频道缓存30条分值效高的文章
        cacheTagToRedis(hotArticleVoList);
        return true;
    }

    /**
     * 为每个频道缓存30条分值较高的文章
     * @param hotArticleVoList
     */
    private void cacheTagToRedis(List<HotArticleVo> hotArticleVoList) {
        //每个频道缓存30条分值较高的文章
        R r = wemediaClient.getAllChannel();
        if(r.getCode().equals(200)){
            String channelJson = JSON.toJSONString(r.getData().get("channelList"));
            List< Channel > channelList = JSON.parseArray(channelJson, Channel.class);
            //检索出每个频道的文章
            if(channelList != null && channelList.size() > 0){
                for (Channel channel : channelList) {
                    List<HotArticleVo> hotArticleVoLists = hotArticleVoList.stream().filter(x -> x.getChannelId().equals(channel.getChannelId())).sorted((a, b) -> b.getScore() - a.getScore()).limit(30).collect(Collectors.toList());
                    //给文章进行排序，取30条分值较高的文章存入redis  key：频道id   value：30条分值较高的文章
                    sortAndCache(hotArticleVoLists, ArticleConstants.HOT_ARTICLE_FIRST_PAGE + channel.getChannelId());
                }
            }
        }


        //设置推荐数据
        List<HotArticleVo> hotArticleVos = hotArticleVoList.stream().sorted((a, b) -> b.getScore() - a.getScore()).limit(30).toList();
        //给文章进行排序，取30条分值较高的文章存入redis  key：频道id   value：30条分值较高的文章
        sortAndCache(hotArticleVos, ArticleConstants.HOT_ARTICLE_FIRST_PAGE + ArticleConstants.DEFAULT_TAG);
    }

    /**
     * 排序并且缓存数据
     * @param hotArticleVos
     * @param key
     */
    private void sortAndCache(List<HotArticleVo> hotArticleVos, String key) {
        hotArticleVos = hotArticleVos.stream().sorted(Comparator.comparing(HotArticleVo::getScore).reversed()).collect(Collectors.toList());
        if (hotArticleVos.size() > 30) {
            hotArticleVos = hotArticleVos.subList(0, 30);
        }
        cacheService.set(key, JSON.toJSONString(hotArticleVos));
    }

    /**
     * 计算文章分值
     * @param articleList
     * @return
     */
    private List<HotArticleVo> computeHotArticle(List<Article> articleList) {

        List<HotArticleVo> hotArticleVoList = new ArrayList<>();

        if(articleList != null && articleList.size() > 0){
            for (Article article : articleList) {
                HotArticleVo hotArticleVo = new HotArticleVo();
                BeanUtils.copyProperties(article,hotArticleVo);
                Integer score = computeScore(article);
                hotArticleVo.setScore(score);
                hotArticleVoList.add(hotArticleVo);
            }
        }
        return hotArticleVoList;
    }

    /**
     * 计算文章的具体分值
     * @param article
     * @return
     */
    private Integer computeScore(Article article) {
        Integer score = 0;
        // 1、文章的阅读数
        if(article.getArticleLikes() != null){
            score += article.getArticleLikes() * ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT;
        }
        // 2、文章的点赞数
        if(article.getArticleViews() != null){
            score += article.getArticleViews();
        }
        // 3、文章的评论数
        if(article.getArticleComment() != null){
            score += article.getArticleComment() * ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT;
        }
        // 4、文章的收藏数
        if(article.getArticleCollection() != null){
            score += article.getArticleCollection() * ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT;
        }

        return score;
    }
}
